﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using IPlugin;

namespace Proyecto_3
{
    //Clase que utilizará a los otros plugins
    public class PluginServices
    {
        //Coleccion con los plugins cargados actualmente
        private System.Collections.ArrayList coleccionPlugins = new System.Collections.ArrayList();

        public System.Collections.ArrayList coleccionDePlugins
        {
            get { return coleccionPlugins; }
        }


        //Al inicializar se deberían buscar los plugins en una carpeta inicial (en este caso, la carpeta donde se encuentra el programa)
        public void BuscarPlugins()
        {
            CargarPlugins(AppDomain.CurrentDomain.BaseDirectory);
        }


        //Cargar los plugins de una carpeta (borra las que había antes cargadas)
        public void CargarPlugins(string Path)
        {
            try
            {
                coleccionPlugins.Clear();

                foreach (string fileOn in Directory.GetFiles(Path))
                {
                    FileInfo file = new FileInfo(fileOn);

                    if (file.Extension.Equals(".dll"))
                    {
                        this.agregarPlugin(fileOn);
                    }

                }
            }
            catch (DirectoryNotFoundException dir)
            {
                //No cargar nada supongo y dejar que el usuario cargue manualmente como siempre
            }
        }


        //Cargar un plugin individual
        public void agregarPlugin(string FileName)
        {
            Assembly pluginAssembly = Assembly.LoadFrom(FileName);

            foreach (Type pluginType in pluginAssembly.GetTypes())
            {
                if (pluginType.IsPublic)
                {
                    if (!pluginType.IsAbstract)
                    {
                        Type typeInterface = pluginType.GetInterface("IPlugin.Plugin", true);

                        if (typeInterface != null)
                        {
                            PluginUsable nuevoPlugin = new PluginUsable();
                            nuevoPlugin.InstanciaPlugin = (Plugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
                            this.coleccionPlugins.Add(nuevoPlugin);
                            nuevoPlugin = null;
                        }

                        typeInterface = null;
                    }
                }
            }
            pluginAssembly = null;
        }


        //Limpiar los plugins de la coleccion y eliminar las instancias
        public void CerrarPlugins()
        {
            coleccionPlugins.Clear();
        }


        public float operarPlugin(string sim, float a, float b)
        {
            float resultado = 0;

            foreach (PluginUsable pluginOn in coleccionPlugins)
            {
                if (pluginOn.InstanciaPlugin.nombre == sim)
                {
                    resultado = pluginOn.InstanciaPlugin.operacion(a, b);
                    break;
                }
                
            }

            return resultado;
        }
    }





    public class PluginUsable
    {
        //Mantiene una instancia del plugin a utilizar
        private Plugin myInstance = null;

        public Plugin InstanciaPlugin
        {
            get { return myInstance; }
            set { myInstance = value; }
        }

    }



    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormCalculadora());
        }
    }
}
